package com.mh.controller;

import com.google.code.kaptcha.Constants;
import com.google.code.kaptcha.Producer;
import com.mh.entity.CheckCode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.IOException;

@Controller
public class KaptchaController {

    //final 关键字表示该属性在对象创建后不能被修改，确保了不可变性
    //这个属性本身只是一个普通的类成员变量,与Spring容器没有直接关系
    private final Producer producer;
    /** @Autowired 加在构造器上,表示Spring需要通过构造器注入Producer的实例
     *  这是一个构造器,接受一个 Producer 类型的参数
     *  这个参数producer是从Spring容器中获取的Producer对象
     *  将构造器参数producer(从Spring容器中获取的对象)赋值给当前类的属性this.producer
     *  由于producer是final的,它只能在构造器中赋值一次
     */
    @Autowired
    public KaptchaController(Producer producer) {
        this.producer = producer;
    }

    //生成验证码并响应给前端,验证码信息存储在session中
    @GetMapping("/code/image")
    public void getCode(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        //1. 生成验证码文本
        String text = producer.createText();

        //2.1 将生成的验证码文本封装到CheckCode对象中
        CheckCode checkCode = new CheckCode(text);
        //2.2 将验证码存储到Session中(后续可以通过Session获取验证码文本进行验证)
        //public static final String KAPTCHA_SESSION_KEY = "KAPTCHA_SESSION_KEY";
        req.getSession().setAttribute(Constants.KAPTCHA_SESSION_KEY, checkCode);

        //3.设置HTTP响应头-->禁止客户端缓存验证码图片,确保每次请求都生成新的验证码
        //3.1 每次请求都会向服务器发起新的请求,而不会使用缓存
        resp.setHeader("Cache-Control", "no-store");
        //3.2 浏览器会向服务器发送请求,询问缓存是否仍然有效
        //如果服务器返回 304 Not Modified,则浏览器使用缓存; 否则,返回新的响应内容
        resp.setHeader("Pragma", "no-cache");
        //3.3 浏览器会将响应内容视为立即过期,不会缓存
        resp.setDateHeader("Expires", 0);

        //4. 设置响应内容类型
        //4.1 表示返回的是 PNG 格式的图片
        resp.setContentType("image/png");
        //4.2 调用 Producer 的 createImage() 方法生成验证码图片
        BufferedImage image = producer.createImage(text);
        //4.3 使用 ImageIO.write() 将图片写入响应输出流，返回给客户端
        ImageIO.write(image,"jpg",resp.getOutputStream());
    }
}
